package com.tang.service.admin.service.impl;

import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.tang.common.properties.sys.CoolTeaProperties;
import com.tang.framework.component.security.model.PermissionAuthority;
import com.tang.framework.core.model.LoginUser;
import com.tang.common.exception.BusinessException;
import com.tang.common.exception.eumes.Error;
import com.tang.service.admin.domain.*;
import com.tang.service.admin.service.ISysMenuService;
import com.tang.service.admin.service.ISysRoleMenuService;
import com.tang.service.admin.service.ISysRoleService;
import com.tang.service.admin.service.ISysUserService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author tang jun liang
 * @Date 2023/2/10 15:11
 */
@Component
public class UserDetailsServiceImpl implements UserDetailsService {


    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysMenuService sysMenuService;

    @Resource
    private ISysRoleMenuService sysRoleMenuService;

    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private CoolTeaProperties coolTeaProperties;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = sysUserService
                .lambdaQuery()
                .eq(SysUser::getNickName, username)
                .one();
        if (Objects.isNull(user)) {
            throw new BusinessException(Error.USERNAME_NOT_EXIST);
        }
        List<SysMenu> sysMenuList = sysUserService
                .selectJoinList(SysMenu.class,
                        new MPJLambdaWrapper<SysUser>()
                                .selectAll(SysMenu.class)
                                .leftJoin(SysUserRole.class, SysUserRole::getSysUserId, SysUser::getId)
                                .leftJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysUserRole::getRoleId)
                                .leftJoin(SysMenu.class, SysMenu::getId, SysRoleMenu::getMenuId)
                                .eq(SysUser::getId, user.getId())
                                .groupBy(SysMenu::getId)
                );
        List<PermissionAuthority> authorities = sysMenuList.stream().map(item -> {
            PermissionAuthority permissionAuthority = new PermissionAuthority();
            permissionAuthority.setPermission(item.getAuthorize());
            return permissionAuthority;
        }).collect(Collectors.toList());
        List<String> menuList = sysMenuList.stream().filter(SysMenu::getMenu)
                .map(SysMenu::getMenuName).collect(Collectors.toList());
        LoginUser loginUser = new LoginUser();
        loginUser.setMenuList(menuList);
        loginUser.setAuthorities(authorities);
        loginUser.setTenantId(user.getTenantId());
        loginUser.setUserId(user.getId());
        loginUser.setUsername(username);
        loginUser.setPhone(user.getPhone());
        loginUser.setUserStatus(user.getStatus());
        loginUser.setDatabaseName(coolTeaProperties.getDatabaseName());
        loginUser.setPassword(user.getPassword());
        return loginUser;
    }
}
